#! /usr/bin/env python
#coding=utf-8

import os
import sys
import traceback

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))

from loader import Product
from loader import ProductMgr
from .resources import *
from graphviz import GraphVizBuilder
import config

from utils import ResterHelper
from utils import ResterStringBuilder

class ProductRest(Product, ResterStringBuilder):
	RESTER_MAP = {
		"modules": ElfModuleRestMgr,
		"deps": DepsRestMgr,
		"records": MemRecordsRestMgr,
		"symbols": SymbolsRestMgr
	}
	def __init__(self, db_info, idx, mgr):
		Product.__init__(self, db_info, idx, mgr)
		self._resters = {}

	def __del__(self):
		self.unload_product()

	def unload_product(self):
		names = self._resters.keys()
		for name in names:
			del self._resters[name]
		self._resters = {}
		Product.unload_product(self)

	def _get_sub_rester(self, name):
		if name in self._resters:
			return self._resters[name]

		if name not in ProductRest.RESTER_MAP:
			return None

		self._resters[name] = ProductRest.RESTER_MAP[name](self)
		return self._resters[name]

	def getMgr(self, name):
		if name in self._resters:
			return self._resters[name]
		return self._get_sub_rester(name)

	def doGetRequest(self, handler, path_parts, xargs):
		path_parts = path_parts[Products.PRODUCT_REST_PREFIX_LEN:]

		xargs["_cur_product"] = self
		xargs["_product_mgr"] = self.getProductMgr()

		sub_rester = self._get_sub_rester(path_parts[0])
		if not sub_rester:
			handler.resFileNotFound()
			return

		# For get all
		if len(path_parts) == 1:
			try:
				res = sub_rester.get_all(xargs)
			except Exception as e:
				print(e)
				res = []
			if type(res) in (str,):
				return handler.resStrContent(res, xargs)
			return handler.resStrContent(ResterHelper.build_array_content(res, xargs), xargs)

		if len(path_parts) < 3:
			handler.resFileNotFound()
			return

		# Do request
		resStr = sub_rester.doRestRequest(path_parts[1], path_parts[2], xargs)
		handler.resStrContent(resStr, xargs)

	def getStr(self, xargs=None, extra_keys=None, extra_vals=None):
		keys = ("id", "product", "version")
		return ResterStringBuilder.getStr(self, xargs, keys, sorted(tuple(ProductRest.RESTER_MAP)))

	def getUrlPrefix(self):
		return os.path.join("/", config.REST_PREFIX, self["product"], self["version"])

class Products(ProductMgr):
	REST_PRODUCTS_NAME="products"
	PRODUCT_REST_PREFIX_LEN=3

	def __init__(self):
		ProductMgr.__init__(self, config.PRODUCT_ROOT_PATH, ProductRest)
		noCache = True
		if config.GRAPHVIZ_ENABLE_CACHE:
			noCache = False
		self._graphviz_builder = GraphVizBuilder(self, no_cache=noCache)

	def getGraphVizBuilder(self):
		return self._graphviz_builder

	def match(self, handler, path_parts):
		if len(path_parts) < 2:
			return None
		if path_parts[0] != config.REST_PREFIX:
			return None

		if path_parts[1] == Products.REST_PRODUCTS_NAME:
			return self

		if len(path_parts) > 3:
			return self.get_product_by_name(path_parts[1], path_parts[2])

		return None

	def doGetRequest(self, handler, path_parts, xargs):
		xargs["_handler"] = handler
		xargs["_product_mgr"] = self
		resStr = ResterHelper.build_array_content(self.get_all(), xargs)
		handler.resStrContent(resStr, xargs)

if __name__ == "__main__":
	product_mgr = Products()
	print(product_mgr.get_all())
